package cz.spock.core.controller;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cz.spock.core.entity.Account;
import cz.spock.core.entity.security.AccountSecurity;
import cz.spock.core.service.AccountService;
import cz.spock.core.service.SpringSecurityService;
import cz.spock.exception.DatabaseException;
import cz.spock.exception.InvalidDataException;
import cz.spock.exception.InvalidInputException;

/**
 * this controller serves admin related requests
 * 
 * still contains some utilities
 * 
 * TODO move some methods to more suitable controllers, get rid of testing methods
 * 
 * @author miso
 *
 */
@Controller
public class AdminController extends BaseController {
    
    @Autowired
    private AccountService accService;
    @Autowired
    private SpringSecurityService secService;
    
    
//    @RequestMapping(value = "/WEB-INF/jsp/login.jsp")
//    public void login2(HttpServletRequest request, HttpServletResponse response) {
//        System.out.println("ooopppsss");
//    }
    
//    @RequestMapping(value = "/login")
//    public ModelAndView login(HttpServletRequest request, HttpServletResponse response) {
//        System.out.println("here");
//        return new ModelAndView("login");
//    }
    
    /**
     * provides access to jsp login, because everything must go via servlets
     */
    @RequestMapping(value = "/web/login", method = RequestMethod.GET)
    public String login(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("i am in logindemo");
        return "login";
    }
    
    /**
     * creates new admin user with credentials:
     * login: admin
     * password: admin
     * 
     * @param request
     * @param response
     */
    @RequestMapping(value = "/admin/create", method = RequestMethod.GET)
    public void createAdmin(HttpServletRequest request, HttpServletResponse response) {
        // calls service
        List<String> roles = new ArrayList<String>();
        roles.add("ROLE_ADMIN");
        roles.add("ROLE_USER");
        try {
            accService.createAccount("admin1", "mknazsky@gmail.com");
            accService.createAccountSecurity("admin1", "admin1", roles, true);
        } catch(InvalidInputException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(InvalidDataException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(DatabaseException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(Exception e) {
            System.out.println(e.getMessage());
            log.severe("Exception in AdminController method createAdmin: " + e.getMessage());
            sendJson(response, accService.errorToJson("Internal error.", 500));
            return;            
        }
        System.out.println("admin created");
    }
    
    @RequestMapping(value = "/admin/create/test", method = RequestMethod.GET)
    public void createAdminTest(HttpServletRequest request, HttpServletResponse response) {
        // calls service
        Account a;
        AccountSecurity as;
        try {
            a = accService.findAccountByLogin("admin1");
            System.out.println("login: " + a.getLogin());
            System.out.println("email: " + a.getEmail().getEmail());
            as = (AccountSecurity) secService.loadUserByUsername("admin1");
            System.out.println("pass: " + as.getPassword());
            for(GrantedAuthority g: as.getAuthorities()) {
                System.out.println(g.getAuthority());
            }
        } catch(InvalidInputException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(InvalidDataException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(DatabaseException e) {
            System.out.println(e.getMessage());
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(Exception e) {
            System.out.println(e.getMessage());
            log.severe("Exception in AdminController method createAdminTest: " + e.getMessage());
            sendJson(response, accService.errorToJson("Internal error.", 500));
            return;            
        }
        try {
            OutputStreamWriter re = new OutputStreamWriter(response.getOutputStream());
            re.write("login: " + a.getLogin() + '\n' + "email: " + a.getEmail().getEmail());
            re.flush();
            re.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("admin created");
    }
    
    @RequestMapping(value = "/admin/home", method = RequestMethod.GET)
    public String getHome(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/admin/home");
        return "admin/home";
    }
    
    @RequestMapping(value = "/admin/project", method = RequestMethod.GET)
    public String getProject(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("/admin/project");
        return "admin/project";
    }

}
